﻿using System;
using System.Linq;
using LuxDiner.Model;
using LuxDiner.Model.Orders;
using LuxDiner.Model.Members;
using LuxDiner.Model.Products;
using Utils;
namespace LuxDiner.Command.Orders
{
    public class DealOrderCommand
    {
        public static DealOrderModel NewOrder(DealOrderModel order)
        {
            if (order != null)
            {
                using (DBCentre db = new DBCentre())
                {
                    var orderMethod = (OrderMethod)Enum.Parse(typeof(OrderMethod), order.Method.ToString());
                    order.OrderNo = Comm.Orders.CreateOrderNo(db, orderMethod);
                    var dOrder = Convertor.ConvertFrom<order_deal, DealOrderModel>(order);
                    var dItems = Convertor.ConvertFromCollection<order_deal_details, DealOrderDetailModel>(order.Items);
                    foreach (var it in dItems)
                        dOrder.order_deal_details.Add(it);
                    db.DataContext.order_deal.Add(dOrder);

                    #region 销售单和采购退货单 检查库存
                    if (order.Method == (int)OrderMethod.XS || order.Method==(int)OrderMethod.CT)
                    {
                        foreach (var it in order.Items)
                        {
                            var repertory = db.DataContext.view_repertory_tops.Where(p => p.ProductID == it.ProductID).FirstOrDefault();
                            if (repertory == null || repertory.Balance - it.Quantity < 0)
                                throw new LuxDinerException(string.Format("{0}-库存不足", it.Product.ProductName));
                        }
                    }
                    #endregion

                    #region 插入费用表
                    if (order.Method == (int)OrderMethod.CT || order.Method == (int)OrderMethod.XT)
                        order.TotalMoney *= -1;
                    var payBalance = order.TotalMoney;
                    var pay = db.DataContext.payments.Where(p => p.CustomerID == order.CustomerID).OrderByDescending(p => p.ID).FirstOrDefault();
                    if (pay != null)
                        payBalance = pay.Balance + order.TotalMoney;
                    if (payBalance < 0)
                        throw new LuxDinerException("这个客户没有足够的余额");
                    var payment = new payment()
                    {
                        CustomerID = order.CustomerID,
                        Money = order.TotalMoney,
                        Description = (order.Method == (int)Model.Orders.OrderMethod.CG) ? "采购单" : "销售单",
                        OrderNo = order.OrderNo,
                        NoteDate = order.NoteDate,
                        CreatedOn = DateTime.Now,
                        OperatorUserID = order.OperatorUserID,
                        Balance = payBalance,
                        Method = order.Method
                    };
                    switch (orderMethod)
                    {
                        case OrderMethod.CG:
                            payment.Description = "采购单";
                            break;
                        case OrderMethod.XS:
                            payment.Description = "销售单";
                            break;
                        case OrderMethod.CT:
                            payment.Description = "采购退货";
                            break;
                        case OrderMethod.XT:
                            payment.Description = "销售退货";
                            break;
                    }
                    db.DataContext.payments.Add(payment);
                    #endregion

                    db.DataContext.SaveChanges();
                    order.ID = dOrder.ID;
                    return order;
                }
            }
            return null;
        }
        /// <summary>
        /// 取得最近一次交易的价格
        /// </summary>
        /// <param name="productID"></param>
        /// <param name="SupplierID"></param>
        /// <returns></returns>
        public static decimal GetLastPrice(int productID, int customerID)
        {
            if (productID > 0 && customerID > 0)
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.order_deal_details.Where(p => p.ProductID == productID && p.order_deal.CustomerID == customerID).OrderByDescending(p => p.ID).FirstOrDefault();
                    if (d != null)
                        return d.UnitPrice;
                }
            }
            return 0;
        }
        /// <summary>
        /// 查询单据列表
        /// </summary>
        /// <param name="sea"></param>
        /// <returns></returns>
        public static DealOrderCollection GetOrders(DealOrderQuery sea)
        {
            var result = new DealOrderCollection();
            using (DBCentre db = new DBCentre())
            {
                IQueryable<order_deal> q = db.DataContext.order_deal;
                if (sea != null)
                {
                    if (!string.IsNullOrEmpty(sea.OrderNo))
                        q = q.Where(p => p.OrderNo == sea.OrderNo);
                    if (sea.CustomerID > 0)
                        q = q.Where(p => p.CustomerID == sea.CustomerID);
                    if (sea.OperatorUserID > 0)
                        q = q.Where(p => p.OperatorUserID == sea.OperatorUserID);
                    if (sea.OrderDateBefore != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateBefore.Value) >= 0);
                    if (sea.OrderDateAfter != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateAfter.Value) <= 0);
                    if (sea.Method!=null && sea.Method.Length > 0)
                        q = q.Where(p =>sea.Method.Contains(p.Method));
                    if (sea.OrderStatus!=null && sea.OrderStatus.Length > 0)
                        q = q.Where(p => sea.OrderStatus.Contains(p.OrderStatus));
                    if (sea.ProductID > 0)
                        q = q.Where(p => p.order_deal_details.Any(o => o.ProductID == sea.ProductID));
                }
                var n = q.Count();
                if (n > 0)
                {
                    var sum=q.Sum(p=>p.TotalMoney);
                    q = q.OrderByDescending(p => p.ID);
                    if (sea != null && sea.PageSize > 0)
                        q = q.Skip(sea.PageSize * sea.PageIndex).Take(sea.PageSize);
                    var lst = q.ToList();
                    result = Convertor.ConvertCollection<DealOrderModel, order_deal, DealOrderCollection>(lst);
                    result.TotalRecordsCount = n;
                    foreach (var m in result)
                    {
                        var d = lst.Find(p => p.OrderNo == m.OrderNo);
                        if (sea.GetCustomer)
                        {
                            m.Customer = Convertor.ConvertTo<CustomerModel, customer>(d.customer);
                            if (sea.GetCustomerCategory)
                                m.Customer.Categories = Convertor.ConvertCollection<CustomerCategoryModel, customer_categories, CustomerCategoryCollection>(d.customer.customer_categories);
                        }
                         
                        if (sea.GetItems)
                        {
                            m.Items = Convertor.ConvertCollection<DealOrderDetailModel, order_deal_details, DealOrderDetailCollection>(d.order_deal_details);
                            if (sea.GetProduct)
                            {
                                foreach (var it in m.Items)
                                {
                                    var dit = d.order_deal_details.First(p => p.ID == it.ID);
                                    it.Product = Convertor.ConvertTo<ProductModel, product>(dit.product);
                                    if (sea.GetProductCategory)
                                        it.Product.Categories = Convertor.ConvertCollection<ProductCategoryModel, product_categories, ProductCategoryCollection>(dit.product.product_categories);
                                }
                            }
                        }
                    }
                    result.Add(new DealOrderModel() { OrderNo = "", Customer = new CustomerModel() { Corporation = "金额汇总：" }, TotalMoney = sum });
                }
            }
            return result;
        }
        /// <summary>
        /// 查询单张单据
        /// </summary>
        /// <param name="orderNo"></param>
        /// <returns></returns>
        public static DealOrderModel GetOrder(string orderNo)
        {
            if (!string.IsNullOrEmpty(orderNo))
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.order_deal.FirstOrDefault(p => p.OrderNo == orderNo);
                    if (d != null)
                    {
                        var m = Convertor.ConvertTo<DealOrderModel, order_deal>(d);
                        m.Customer = Convertor.ConvertTo<CustomerModel, customer>(d.customer);
                        m.Items = Convertor.ConvertCollection<DealOrderDetailModel, order_deal_details, DealOrderDetailCollection>(d.order_deal_details);
                        foreach (var o in m.Items)
                        {
                            var di = d.order_deal_details.FirstOrDefault(p => p.ID == o.ID);
                            o.Product = Convertor.ConvertTo<ProductModel, product>(di.product);
                        }
                        return m;
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 查询单张单据
        /// </summary>
        /// <param name="orderNo"></param>
        /// <returns></returns>
        public static DealOrderModel GetOrderWithProductOrders(string orderNo)
        {
            if (!string.IsNullOrEmpty(orderNo))
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.order_deal.FirstOrDefault(p => p.OrderNo == orderNo);
                    if (d != null)
                    {
                        var m = Convertor.ConvertTo<DealOrderModel, order_deal>(d);
                        m.Customer = Convertor.ConvertTo<CustomerModel, customer>(d.customer);
                        m.Items = Convertor.ConvertCollection<DealOrderDetailModel, order_deal_details, DealOrderDetailCollection>(d.order_deal_details);
                        foreach (var o in m.Items)
                        {
                            var di = d.order_deal_details.FirstOrDefault(p => p.ID == o.ID);
                            o.Product = Convertor.ConvertTo<ProductModel, product>(di.product);
                        }
                        m.ProductOrders = Convertor.ConvertCollection<ProductOrderModel, order_product, ProductOrderCollection>(d.order_product);
                        m.ProductOrders.ForEach(p => {
                            var po = d.order_product.FirstOrDefault(o => o.ID == p.ID);
                            p.Items = Convertor.ConvertCollection<ProductOrderDetailModel, order_product_details, ProductOrderDetailCollection>(po.order_product_details);
                        });
                        return m;
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 撤消交易单据
        /// </summary>
        /// <param name="orderNo"></param>
        /// <returns></returns>
        public static bool CancelOrder(string orderNo)
        {
            if (!string.IsNullOrEmpty(orderNo))
            {
                using (DBCentre db = new DBCentre())
                {
                    var order = db.DataContext.order_deal.FirstOrDefault(p => p.OrderNo == orderNo);
                    if (order != null)
                    {
                        #region 检查是否可以删除这个单据
                        if (order.order_product != null && order.order_product.Count() > 0)
                            throw new LuxDinerException("不能撤消这个单据,因为有库存单据。");
                        var pay = db.DataContext.payments.FirstOrDefault(p => p.OrderNo == order.OrderNo);
                        if (pay != null)
                        {
                            if (db.DataContext.payments.Any(p => p.CustomerID == order.CustomerID && p.ID > pay.ID))
                                throw new LuxDinerException("不能撤消这个单据,因为有更新的费用单据。");
                        }
                        #endregion

                        db.DataContext.order_deal.Remove(order);
                        db.Delete<payment>(p => p.OrderNo == orderNo);
                        db.DataContext.SaveChanges();
                        return true;
                    }
                    else
                        throw new LuxDinerException("无效的单据编号。");
                }
            }
            return false;
        }
        /// <summary>
        /// 查询单据明细列表
        /// </summary>
        /// <param name="sea"></param>
        /// <returns></returns>
        public static VDealOrderDetailsCollection GetOrderDetails(DealOrderQuery sea)
        {
            var result = new VDealOrderDetailsCollection();
            using (DBCentre db = new DBCentre())
            {
                IQueryable<view_order_deal_details> q = db.DataContext.view_order_deal_details;
                if (sea != null)
                {
                    if (!string.IsNullOrEmpty(sea.OrderNo))
                        q = q.Where(p => p.OrderNo == sea.OrderNo);
                    if (sea.CustomerID > 0)
                        q = q.Where(p => p.CustomerID == sea.CustomerID);
                    if (sea.OperatorUserID > 0)
                        q = q.Where(p => p.OperatorUserID == sea.OperatorUserID);
                    if (sea.OrderDateBefore != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateBefore.Value) >= 0);
                    if (sea.OrderDateAfter != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateAfter.Value) <= 0);
                    if (sea.Method != null && sea.Method.Length > 0)
                        q = q.Where(p => sea.Method.Contains(p.Method));
                    if (sea.OrderStatus != null && sea.OrderStatus.Length > 0)
                        q = q.Where(p => sea.OrderStatus.Contains(p.OrderStatus));
                    if (sea.ProductID > 0)
                        q = q.Where(p => p.ProductID == sea.ProductID);
                }
                var n = q.Count();
                if (n > 0)
                {
                    var sum = q.Sum(p => p.Quantity * p.UnitPrice);
                    q = q.OrderByDescending(p => p.ID);
                    if (sea != null && sea.PageSize > 0)
                        q = q.Skip(sea.PageSize * sea.PageIndex).Take(sea.PageSize);
                    var lst = q.ToList();
                    result = Convertor.ConvertCollection<VDealOrderDetailsModel, view_order_deal_details, VDealOrderDetailsCollection>(lst);
                    result.TotalRecordsCount = n;
                    result.Add(new VDealOrderDetailsModel() { OrderNo = "", ProductName = "金额汇总：", Quantity = 1, UnitPrice = sum, UnitName = "个" });
                }
            }
            return result;
        }
    }
}
